package com.zj;


import java.util.HashSet;
import java.util.concurrent.TimeUnit;

public class ZjThreadPool {

    private ZjBlockingQueue<Runnable> taskQueue;

    private HashSet<ZjWorker> workers=new HashSet<ZjWorker>();

    private int coreSize;

    private long timeout;

    private RejectHandler handler;

    public ZjThreadPool(int coreSize, long timeout, TimeUnit unit,int queCapcity,RejectHandler handler) {
        this.taskQueue = new ZjBlockingQueue<>(queCapcity);
        this.coreSize = coreSize;
        this.timeout = timeout;
        this.unit = unit;
        this.handler=handler;
    }

    public void execute(Runnable task){
        synchronized (workers){
            if(workers.size()<coreSize){
                ZjWorker worker=new ZjWorker(task);
                workers.add(worker);
                System.out.println("新增worker"+worker+",task"+task);
                worker.start();
            }else {
                if(!taskQueue.offer(task,0L,TimeUnit.SECONDS)){
                    handler.rejectedExecution(task, this);
                }
            }
        }
    }

    public ZjBlockingQueue<Runnable> getTaskQueue() {
        return taskQueue;
    }

    public void setTaskQueue(ZjBlockingQueue<Runnable> taskQueue) {
        this.taskQueue = taskQueue;
    }

    public int getCoreSize() {
        return coreSize;
    }

    public void setCoreSize(int coreSize) {
        this.coreSize = coreSize;
    }

    public long getTimeout() {
        return timeout;
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }

    public TimeUnit getUnit() {
        return unit;
    }

    public void setUnit(TimeUnit unit) {
        this.unit = unit;
    }

    private TimeUnit unit;

    class ZjWorker extends  Thread{
        private Runnable task;

        public ZjWorker(Runnable task){
            this.task=task;
        }
        public void run(){
            //当task不为空，执行任务。
            //当tsk执行完毕，再从队列中获取任务执行。
            while (task!=null||(task=taskQueue.poll(timeout,unit))!=null){
                try{
                    task.run();
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    task=null;
                }
            }
            synchronized (workers){
                System.out.println("remove "+this);
                workers.remove(this);
            }
        }

    }
}
